#include "Menu.h"
#include <iostream>

//additional includes
#include <fstream>
#include "Chrono.h"			//KLB A2
#include <sstream>
#include <stdlib.h>

#include "ShowFindUpdateKR.h"
#include "ShowfindupdateTMD.h"
#include "ShowFindUpdate.h"
#include "OtherKR.h"
#include "OtherTMD.h"
#include "OtherKLB.h"
#include "SubKR.h"

using namespace std;

Menu::Menu()
{
}

void Menu::display_main_menu() const 
{
	cout << "Here is the MAIN MENU" << endl; // changed newline to endl so that the line is always printed
    //Begin TD A3
	cout << "Type \'1\' for Information" << endl;
	cout << "Type \'2\' to enter a file name and store data" << endl; 
	cout << "Type \'3\' to show stored data" << endl; 
	cout << "Type \'4\' to find totals" << endl; 
	cout << "Type \'5\' to update stored data" << endl; 
	cout << "Type \'6\' for other options" << endl; 
	cout << "Type \'7\' to exit" << endl;
	//End TD A3
}
void Menu::display_info() const
{
	cout << "Here is the Info requested \n";//display Project Part I, team name and team members
	cout << "------------------ Project Part I ------------------\n\n"			//KLB A2
		 << "Team Name: Blue-GHI-6\n"											//KLB A2
		 << "Team Members: \t- Karunia Ramadhan\n"								//KLB A2
		 << "\t\t- Taylor M. Dowlen\n"											//KLB A2
		 << "\t\t- Kelly Luk Bounsawat\n\n"										//KLB A2
		 << "----------------------------------------------------\n";			//KLB A2
}

void Menu::read()
{
//begin TD A3
  int choice = 0;
  cout << "Type \'1\' for category and product data" << endl; 
  cout << "Type \'2\' for customer data" << endl;
  cout << "Type \'3\' for cart and cart item data" << endl; 
  cin >> choice; //choose what type of file to enter
  while (choice != 1 && choice != 2 && choice !=3)
  {
    cerr << "The number entered was not 1,2, or 3. Try Again!" << endl;
	cin.clear();
	cin.ignore();
	cin >> choice;
  }
  cout << "Please enter the input file name" << endl; //change instructions to make it more clear to the user
  string input;
  cin >> input; //get input file
  switch(choice)
  {
    case 1:
	{
      ifstream ist(input.c_str()); //create a low level string 
      if(ist.is_open())
      {
        int cat_count = -1;
        ist >> 	cat_count;
	    if(cat_count < 0)
	    {
	      throw InvalidData();
	      return;
	    }
	    int i;
	    for(i=0; i < cat_count; ++i)
	    {
	      int cat_id;
	      string cat_name;
	      ist >> cat_id >> cat_name;
          Category cat = Category(cat_id, cat_name);
	      cats.push_back(cat);
	    }
	    int prod_count = -1;
	    ist >> prod_count;
	    if(prod_count < 0)
	    {
	      throw InvalidData();
	      return;
	    }
	    for(i=0; i < prod_count; ++i)
	    {
	      int prod_id;
	      int cat_id;
	      string prod_name;
	      double price;
	      ist >> prod_id >> cat_id >> prod_name >> price;
          Product prod = Product(prod_id, cat_id, prod_name, price);
	      prods.push_back(prod);
	    }
	    ist.close();
	  }
	break;
	}
		//End TD A3
	case 2:
	{
/* Begin KR - A1 */
	string 	line;
	int 	cust_num;
	ifstream cust_file(input.c_str());

	//If file is opened
	if (cust_file.is_open()) {
		//Get first line to get customer data size
		getline(cust_file, line);
		cust_num = atoi(line.c_str());		
	
		//Read line according customer data
		for(int i=0;i<cust_num;i++) {
			//Read one data
			getline(cust_file, line);

			//Create local string stream
			istringstream iss(line);

			//Create local variables for customer data
			int 	id, addr_no, addr_postal;
			string 	buffer, name, addr_name;

			//Read customer data
			iss >> buffer;
			id = atoi(buffer.c_str());
			iss >> name;
			iss >> buffer;
			addr_no = atoi(buffer.c_str());
			iss >> addr_name;
			iss >> buffer;
			addr_postal = atoi(buffer.c_str());			

			//cout << id << " "<< name << " " << addr_no << " " << addr_name << " " << addr_postal << endl;

			//Create customer data
			Street_address 	addr = Street_address(addr_no, addr_name, addr_postal);
			Customer 		cust = Customer(id, name, addr);

			//Put it into the vector
			custs.push_back(cust);
		}

		//cout << custs.size() << endl;

		//Close file
		cust_file.close();
		break;
	}

	/* End KR - A1 */
	}
	case 3:
	{
		ifstream cartFile(input.c_str(), ifstream::in);	//KLB A2
	
	int num_cart;										//KLB A2
	cartFile >> num_cart;								//KLB A2
	for( int i = 0; i < num_cart; ++i)					//KLB A2
	{
		int cartId;								//KLB A2
		int custId;								//KLB A2
		int year;								//KLB A2
		int month;								//KLB A2
		int day;								//KLB A2
		
		cartFile >> cartId >> custId >> year >> month >> day;	//KLB A2
		Date x(year, Date::Month(month), day);					//KLB A2
		Cart c(cartId, custId, x);								//KLB A2
		carts.push_back(c);										//KLB A2
		
	}
	
	cartFile >> num_cart;										//KLB A2
	for( int y = 0; y < num_cart; ++y)							//KLB A2
	{
		int cart_id;											//KLB A2
		int cust_id;											//KLB A2
		int prod_id;											//KLB A2
		int prod_qty;											//KLB A2
		
		cartFile >> cart_id >> cust_id >> prod_id >> prod_qty;	//KLB A2
		Cart_item info(cart_id, cust_id, prod_id, prod_qty);	//KLB A2
		cart_items.push_back(info);								//KLB A2
	}
	break;
  }
}
}
void Menu::show() const 
{
	cout << "Enter \'1\' to view all categories sorted by category ID" << endl;
	cout << "Enter \'2\' to view all customers sorted name" << endl;
	cout << "Enter \'3\' to view all products sorted by price" << endl;
	int choice = 0;
	cin >> choice; //choose what type of file to 
    while (choice != 1 && choice != 2 && choice !=3)
    {
      cerr << "The number entered was not 1,2, or 3. Try Again!" << endl;
      cin.clear();
      cin.ignore();
	  cin >> choice;
    }
	switch(choice)
    {
      case 1:
	  {
	    ShowfindupdateTMD::show(cats, prods);
		break;
	  }
	  case 2:
	  {
	    ShowFindUpdateKR::Show(custs); // KR - S2
		break;
	  }
	  case 3:
	  {
	    ShowFindUpdateKLB::show(prods);		//added
		break;
	  }
	}
}
void Menu::find() const 
{
	cout << "Enter \'1\' to display total sales for a given product" << endl;
	cout << "Enter \'2\' to calculate total sales for a given customer" << endl;
	cout << "Enter \'3\' to calculate total sales for a given category" << endl;
	int choice = 0;
	cin >> choice; //choose what type of file to enter
    while (choice != 1 && choice != 2 && choice !=3)
    {
      cerr << "The number entered was not 1,2, or 3. Try Again!" << endl;
      cin.clear();
      cin.ignore();
	  cin >> choice;
    }
	switch(choice)
    {
      case 1:
	  {
        ShowfindupdateTMD::find(cart_items, prods);
		break;
	  }
	  case 2:
	  {
	    ShowFindUpdateKR::Find(carts,cart_items,prods);		// KR - S2
		break;
	  }
	  case 3:
	  {
	    ShowFindUpdateKLB::find(cats, prods, cart_items);		//added
		break;
	  }
	}
}
void Menu::update()  
{
	cout << "Enter \'1\' to add a new product to an existing category" << endl;
	cout << "Enter \'2\' to add a new customer" << endl;
	cout << "Enter \'3\' to add a new cart item to an existing cart" << endl;
	int choice = 0;
	cin >> choice; //choose what type of file to enter
    while (choice != 1 && choice != 2 && choice !=3)
    {
      cerr << "The number entered was not 1,2, or 3. Try Again!" << endl;
      cin.clear();
      cin.ignore();
	  cin >> choice;
    }
	switch(choice)
    {
      case 1:
	  {
        ShowfindupdateTMD::update(cats, prods);
		break;
	  }
	  case 2:
	  {
	    ShowFindUpdateKR::Update(&custs);      // KR - S2
		break;
	  }
	  case 3:
	  {
	    ShowFindUpdateKLB::update(cart_items);					//added
		break;
	  }
	}
}
//begin TD C-1
void Menu::other()
{
  cout << "Type \'1\' to delete a product from a category" << endl;
  cout << "Type \'2\' to change the price of a given product" << endl; 
  cout << "Type \'3\' to add a new category" << endl; 
  cout << "Type \'4\' to list all product names and cost in a given cart by ID" << endl; 
  cout << "Type \'5\' to add a new cart given a customer and a date" << endl; 
  cout << "Type \'6\' to delete a cart_item from a cart" << endl; 
  cout << "Type \'7\' to write all program data back to disk" << endl;
  cout << "Type \'8\' to check that no cart_item refers to a non-existent product" << endl; 
  cout << "Type \'9\' to check that every cart has at least one cart_item" << endl;
  cout << "Type \'10\' to check that no product has a price less than or equal to zero" << endl;
  int choice = 0;
  cin >> choice; //choose what type of file to enter
  while (choice > 10 || choice < 1)
  {
    cerr << "The number entered was not 1-10. Try Again!" << endl;
    cin.clear();
    cin.ignore();
	cin >> choice;
  }
  switch(choice)
  {
    case 1:
	{
      OtherTMD::delete_product(prods);
	  break;
	}
	case 2:
	{
	  OtherTMD::change_price(prods);
	  break;
	}
	case 3:
	{
	  OtherTMD::add_category(cats);
	  break;
	}
    case 4:
	{
	  OtherKLB::listProdNames(prods, carts, cart_items);
	  break;
	}
	case 5:
	{
      OtherKLB::addCart(carts);
	  break;
	}
	case 6:
	{
	  OtherKLB::deleteCartItem(cart_items);      // KR - C2					//added
	  break;
	}
    case 7:
	{
      OtherKR::writeProducts("catprd.dat", Menu::getCategories(), Menu::getProducts());
      OtherKR::writeCustomers("cust.dat", Menu::getCustomers());
      OtherKR::writeCarts("carts.dat", Menu::getCarts(), Menu::getCartItems(), Menu::getProducts());  //KR-C3
	  break;
	}
	case 8:
	{
	  bool buffer=true;
	  int i;
	  for(i=0; i < cart_items.size(); ++i)
	  {
        if(!(SubKR::isCartItemValid(cart_items[i], prods)))
		{
		  cerr << "Cart Item " << cart_items[i].item_get() << " refers to a nonexistant product" << endl;
		  buffer=false;
		}
	  }
	  if(buffer)
	  {
	    cout << "No cart_items refer to a non-existent product" << endl;
	  }
	  break;
	}
	case 9:
	{
	  bool buffer=true;
	  int i;
	  for(i=0; i < carts.size(); ++i)
	  {
        if(!(SubKR::isCartValid(carts[i], cart_items)))
		{
		  cerr << "Cart " << carts[i].cart_get() << " has no items" << endl;
		  buffer=false;
		}
	  }
	  if(buffer)
	  {
	    cout << "All carts have at least one item" << endl;
	  }
	  break;
	}
    case 10:
	{
	  bool buffer=true;
	  int i;
	  for(i=0; i < prods.size(); ++i)
	  {
        if(!(SubKR::isProductValid(prods[i])))
		{
		  cerr << "Product " << prods[i].id_get() << " has a price less than zero" << endl;
		  buffer=false;
		}
	  }
	  if(buffer)
	  {
	    cout << "There are no products with price less than zero." << endl;
	  }
	  break;
	}
  }
}
//end TD C-1

/* Begin KR - C3 */

//Getter for the vector data
vector<Category>        Menu::getCategories()   const {         return cats;            }
vector<Product>         Menu::getProducts()     const {         return prods;           }
vector<Customer>        Menu::getCustomers()    const {         return custs;           }
vector<Cart>            Menu::getCarts()        const {         return carts;           }
vector<Cart_item>       Menu::getCartItems()    const {         return cart_items;      }

/* End KR - C3 */
